#pragma once
#include "Test.service.message.pb.h"
#include "XyNet/Service/RpcArgument.h"
#include "XyNet/Service/RpcCallback.h"
#include "XyNet/Channel/RpcChannel.h"
#include "XyNet/Service/RpcController.h"
#include "XyNet/Service/RpcMethod.h"
#include "XyNet/Service/RpcService.h"

namespace XyNetTest
{

class ServerUserService : public XyNet::RpcService
{
public:
	class LoginMethod : public XyNet::RpcMethod
	{
	public:
		typedef ServerUserServiceMessage::LoginRequest Request;
		typedef ServerUserServiceMessage::LoginResponse Response;

		class Controller : public XyNet::RpcController
		{
		public:
			Controller(XyNet::RpcSocketChannel* socketChannel);

			virtual shared_ptr<XyNet::RpcError> createError(int code) const override;

		public:
			static const int AlreadyLogin = 0x922FEB8C;
		};

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		LoginMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onLogin(LoginMethod::Argument* argument) = 0;

	class LogoutMethod : public XyNet::RpcMethod
	{
	public:
		typedef ServerUserServiceMessage::LogoutRequest Request;
		typedef ServerUserServiceMessage::LogoutResponse Response;

		class Controller : public XyNet::RpcController
		{
		public:
			Controller(XyNet::RpcSocketChannel* socketChannel);

			virtual shared_ptr<XyNet::RpcError> createError(int code) const override;

		public:
			static const int AlreadyLogout = 0xC7F45C36;
		};

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		LogoutMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onLogout(LogoutMethod::Argument* argument) = 0;

	ServerUserService();

	virtual shared_ptr<XyNet::RpcArgument> createMethodArgument(int methodId) const override;
	virtual void onMethod(int methodId, XyNet::RpcArgument* argument) override;
};

class ClientUserService : public XyNet::RpcService
{
public:
	class ElsewhereLoginMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientUserServiceMessage::ElsewhereLoginRequest Request;
		typedef ClientUserServiceMessage::ElsewhereLoginResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		ElsewhereLoginMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onElsewhereLogin(ElsewhereLoginMethod::Argument* argument) = 0;

	class OtherLoginMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientUserServiceMessage::OtherLoginRequest Request;
		typedef ClientUserServiceMessage::OtherLoginResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		OtherLoginMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onOtherLogin(OtherLoginMethod::Argument* argument) = 0;

	class OtherLogoutMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientUserServiceMessage::OtherLogoutRequest Request;
		typedef ClientUserServiceMessage::OtherLogoutResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		OtherLogoutMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onOtherLogout(OtherLogoutMethod::Argument* argument) = 0;

	ClientUserService();

	virtual shared_ptr<XyNet::RpcArgument> createMethodArgument(int methodId) const override;
	virtual void onMethod(int methodId, XyNet::RpcArgument* argument) override;
};

class ServerChatService : public XyNet::RpcService
{
public:
	class PublicSayMethod : public XyNet::RpcMethod
	{
	public:
		typedef ServerChatServiceMessage::PublicSayRequest Request;
		typedef ServerChatServiceMessage::PublicSayResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		PublicSayMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onPublicSay(PublicSayMethod::Argument* argument) = 0;

	class PrivateSayMethod : public XyNet::RpcMethod
	{
	public:
		typedef ServerChatServiceMessage::PrivateSayRequest Request;
		typedef ServerChatServiceMessage::PrivateSayResponse Response;

		class Controller : public XyNet::RpcController
		{
		public:
			Controller(XyNet::RpcSocketChannel* socketChannel);

			virtual shared_ptr<XyNet::RpcError> createError(int code) const override;

		public:
			static const int TargetUserNotLogin = 0x2F0E26A9;
		};

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		PrivateSayMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onPrivateSay(PrivateSayMethod::Argument* argument) = 0;

	ServerChatService();

	virtual shared_ptr<XyNet::RpcArgument> createMethodArgument(int methodId) const override;
	virtual void onMethod(int methodId, XyNet::RpcArgument* argument) override;
};

class ClientChatService : public XyNet::RpcService
{
public:
	class PushMessageMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientChatServiceMessage::PushMessageRequest Request;
		typedef ClientChatServiceMessage::PushMessageResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		PushMessageMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onPushMessage(PushMessageMethod::Argument* argument) = 0;

	class OtherPublicSayMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientChatServiceMessage::OtherPublicSayRequest Request;
		typedef ClientChatServiceMessage::OtherPublicSayResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		OtherPublicSayMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onOtherPublicSay(OtherPublicSayMethod::Argument* argument) = 0;

	class OtherPrivateSayMethod : public XyNet::RpcMethod
	{
	public:
		typedef ClientChatServiceMessage::OtherPrivateSayRequest Request;
		typedef ClientChatServiceMessage::OtherPrivateSayResponse Response;

		typedef XyNet::RpcController Controller;

		class Argument : public XyNet::RpcArgument
		{
		public:
			Argument();

			shared_ptr<Controller> getController();
			shared_ptr<const Request> getRequest() const;
			shared_ptr<Response> getResponse();

		private:
			virtual shared_ptr<XyNet::RpcArgument> clone() override;
			virtual void initializeController(XyNet::RpcSocketChannel* socketChannel) override;
		};

		class Callback : public XyNet::RpcCallback
		{
		public:
			Callback(shared_ptr<XyNet::RpcArgument> argument,
				const function<void(Argument*)>& responseHandler,
				const function<void(Argument*)>& exceptionHandler);

		private:
			virtual shared_ptr<XyNet::RpcCallback> clone() override;
			virtual void doResponseHandler() override;
			virtual void doExceptionHandler() override;

		private:
			function<void(Argument*)> _responseHandler;
			function<void(Argument*)> _exceptionHandler;
		};

		OtherPrivateSayMethod(shared_ptr<XyNet::RpcChannel> channel);

		shared_ptr<Request> getRequest();
		void call(
			const function<void(Argument*)>& responseHandler =
			function<void(Argument*)>(),
			const function<void(Argument*)>& exceptionHandler =
			function<void(Argument*)>());

	private:
		shared_ptr<XyNet::RpcChannel> _channel;
		shared_ptr<Argument> _argument;
	};

	virtual void onOtherPrivateSay(OtherPrivateSayMethod::Argument* argument) = 0;

	ClientChatService();

	virtual shared_ptr<XyNet::RpcArgument> createMethodArgument(int methodId) const override;
	virtual void onMethod(int methodId, XyNet::RpcArgument* argument) override;
};

}
